<template>
  <BasicTable
    :initial-params="initialParams"
    :form-rules="formRules"
    :query-api="fetchList"
    :create-api="createRole"
    :update-api="updateRole"
    :delete-api="deleteRole"
    :query-fields="queryFields"
    :table-fields="tableFields"
    :form-fields="formFields"
    :button-permissions="buttonPermissions"
  ></BasicTable>
  <el-drawer v-model="drawerVisible" title="分配权限">
    <el-tree
      ref="treeRef"
      v-loading="loading"
      :data="treeData"
      :props="menuProps"
      show-checkbox
      :default-expand-all="true"
      node-key="name"
      :check-strictly="true"
    >
    </el-tree>
    <template #footer>
      <el-button type="primary" @click="handleConfirmAssignMenu"
        >确定</el-button
      >
      <el-button @click="handleCancelAssignMenu">取消</el-button>
    </template>
  </el-drawer>
</template>

<script setup lang="tsx">
import { ElMessage } from "element-plus";
import TreeStore from "element-plus/es/components/tree/src/model/tree-store";
import { cloneDeep } from "lodash";
import { onMounted, ref } from "vue";
import {
  createRole,
  deleteRole,
  fetchList,
  getOneRole,
  updateRole,
} from "../../api/role";
import BasicTable from "../../components/BasicTable";
import { asyncRoutes } from "../../router";

const initialParams = {
  name: "",
  limit: 99999,
};

const formRules = {
  name: [{ required: true, message: "请输入名称" }],
};

const queryFields = [
  {
    prop: "name",
    title: "名称",
  },
];

const tableFields = [
  {
    prop: "name",
    title: "角色名称",
  },
  {
    prop: "description",
    title: "描述",
  },
  {
    title: "操作",
    action: true,
    slot: (row) => (
      <el-button
        v-has={buttonPermissions.permission}
        link
        type="success"
        onClick={() => handleAssignMenu({ drawerVisible, row })}
      >
        分配权限
      </el-button>
    ),
  },
];

const formFields = [
  {
    prop: "name",
    title: "角色名称",
  },
  {
    prop: "description",
    title: "描述",
    slot: (form) => (
      <el-input
        type="textarea"
        rows={5}
        v-model={form.value.description}
      ></el-input>
    ),
  },
];

const drawerVisible = ref(false);

const menuProps = {
  label: (data) => {
    return data.meta.title;
  },
};

let roleId = "";

async function handleAssignMenu({ drawerVisible, row }) {
  drawerVisible.value = true;
  roleId = row.id;
  loading.value = true;
  try {
    const res = await getOneRole(row.id);
    const keys = res.data.menuList ? res.data.menuList.split(",") : [];
    treeRef.value.setCheckedKeys(keys);
  } finally {
    loading.value = false;
  }
}

const treeRef = ref<TreeStore>(null);

const loading = ref(false);

async function handleConfirmAssignMenu() {
  loading.value = true;
  try {
    const data = {
      id: roleId,
      menuList: treeRef.value.getCheckedKeys().join(","),
    };
    await updateRole(data);
    ElMessage({ type: "success", message: "关联成功" });
    drawerVisible.value = false;
  } finally {
    loading.value = false;
  }
}

function handleCancelAssignMenu() {
  drawerVisible.value = false;
}

onMounted(() => {
  getTreeData();
});

function getTreeData() {
  const routes = cloneDeep(asyncRoutes);
  extractButtons(routes);
  treeData.value = routes;
}

const treeData = ref([]);

function extractButtons(routes) {
  routes.forEach((route) => {
    if (route.children && route.children.length > 0) {
      extractButtons(route.children);
    } else {
      if (route.meta.buttons && route.meta.buttons.length > 0) {
        route.children = route.meta.buttons;
      }
    }
  });
}

const buttonPermissions = {
  create: "authority-role:create",
  edit: "authority-role:edit",
  delete: "authority-role:delete",
  permission: "authority-role:permission",
};
</script>
